

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>Mantle &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/jquery.js"></script>
        <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
        <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/doctools.js"></script>
        <script src="../../_static/sphinx_highlight.js"></script>
    
    <script type="text/javascript" src="../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../genindex/" />
    <link rel="search" title="Search" href="../../search/" />
    <link rel="next" title="指标" href="../metrics/" />
    <link rel="prev" title="LibCephFS (Python 接口)" href="../api/libcephfs-py/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../../" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="../">Ceph 文件系统</a></li>
      <li class="breadcrumb-item active">Mantle</li>
      <li class="wy-breadcrumbs-aside">
            <a href="../../_sources/cephfs/mantle.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../" class="icon icon-home"> Ceph
          

          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../start/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../">Ceph 文件系统</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../#cephfs">CephFS 入门</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id4">管理</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id5">挂载 CephFS</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id6">CephFS 内幕</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../#id7">故障排除和灾难恢复</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../eviction/"> 驱逐客户端</a></li>
<li class="toctree-l3"><a class="reference internal" href="../scrub/"> 洗刷</a></li>
<li class="toctree-l3"><a class="reference internal" href="../full/"> 文件系统占满的处理</a></li>
<li class="toctree-l3"><a class="reference internal" href="../disaster-recovery-experts/"> 元数据修复</a></li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting/"> 故障排除</a></li>
<li class="toctree-l3"><a class="reference internal" href="../disaster-recovery/"> 灾难恢复</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cephfs-journal-tool/"> cephfs-journal-tool</a></li>
<li class="toctree-l3"><a class="reference internal" href="../recover-fs-after-mon-store-loss/"> 监视器存储丢失后恢复文件系统</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="../#id8">开发者指南</a><ul class="current">
<li class="toctree-l4"><a class="reference internal" href="../journaler/"> Journaler 配置</a></li>
<li class="toctree-l4"><a class="reference internal" href="../capabilities/"> 客户端的能力</a></li>
<li class="toctree-l4"><a class="reference internal" href="../api/"> Java 和 Python 捆绑库</a></li>
<li class="toctree-l4 current"><a class="current reference internal" href="#"> Mantle</a></li>
<li class="toctree-l4"><a class="reference internal" href="../metrics/">指标</a></li>
<li class="toctree-l4"><a class="reference internal" href="../metrics/#id3">查看指标</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../#id9">更多细节</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../monitoring/">监控概览</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/developer_guide/">开发者指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../hardware-monitoring/">硬件监控</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <section id="mantle">
<h1>Mantle<a class="headerlink" href="#mantle" title="Permalink to this heading"></a></h1>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Mantle 的初衷是用于研究和开发元数据均衡算法，
不是给 CephFS 生产集群用的。</p>
</div>
<p>Mantle 是内置于 MDS 的可编程元数据均衡器。</p>
<p>默认情况下（没有 Mantle 时），多个活跃 MDS 可以迁移目录，
以均衡元数据载荷。决定何时、何地、迁移多少的策略是硬编码在元数据均衡模块中的。</p>
<p>Mantle 工作方式是保护负载均衡的机制
（迁移、复制、分片），同时用 Lua 脚本抑制均衡策略。
Mantle 基于 [1] ，
但目前的实现还不具备该论文说的以下功能：</p>
<ol class="arabic simple">
<li><p>均衡 API ：在该论文中，用户需要填写何时、何地、
多少以及负载计算策略。目前，
Mantle 只要求 Lua 策略返回一张目标负载表
（例如，向每个 MDS 分配多少负载）。</p></li>
<li><p>“多少”钩子：在论文中，有一个钩子允许用户控制
“分片选择器策略（ fragment selector policy ）”。
目前， Mantle 没有这个钩子。</p></li>
<li><p>作为指标的“ CPU 瞬时利用率”。</p></li>
</ol>
<p>[1] Supercomputing ‘15 论文：
<a class="reference external" href="http://sc15.supercomputing.org/schedule/event_detail-evid=pap168.html">http://sc15.supercomputing.org/schedule/event_detail-evid=pap168.html</a></p>
<section id="vstart">
<h2>vstart 快速入门<a class="headerlink" href="#vstart" title="Permalink to this heading"></a></h2>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>使用 vstart 开发均衡器很困难，因为在一个节点上运行所有守护进程和客户端会使系统超载。让系统运行一段时间，
即使可能会出现许多心跳丢失警告和许多 MDS 滞后警告。
大多数情况下，本指南都有用，但有时在使用 vstart 开发时，
所有 MDS 都会锁死，实际上看不到它们溢出。最好在多节点集群上运行。</p>
</div>
<p>作为前提条件，我们假设您已经安装了 <a class="reference external" href="https://sourceforge.net/projects/mdtest/">mdtest</a>
或已经拉取了 <a class="reference external" href="https://hub.docker.com/r/michaelsevilla/mdtest/">Docker 镜像</a> 。
我们使用 mdtest ，是因为需要产生足够的负载，才能超过均衡器中任意设置的 MIN_OFFLOAD 阈值。例如，下面的不会产生足够的元数据负载：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="n">true</span><span class="p">;</span> <span class="n">do</span>
  <span class="n">touch</span> <span class="s2">&quot;/cephfs/blah-`date`&quot;</span>
<span class="n">done</span>
</pre></div>
</div>
<section id="mantle-vstart-sh">
<h3>Mantle 和 <cite>vstart.sh</cite> 调试<a class="headerlink" href="#mantle-vstart-sh" title="Permalink to this heading"></a></h3>
<ol class="arabic simple">
<li><p>启动 Ceph 并调整日志记录，我们才能看到是否有迁移：</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>cd build
../src/vstart.sh -n -l
for i in a b c; do
  bin/ceph --admin-daemon out/mds.$i.asok config set debug_ms 0
  bin/ceph --admin-daemon out/mds.$i.asok config set debug_mds 2
  bin/ceph --admin-daemon out/mds.$i.asok config set mds_beacon_grace 1500
done
</pre></div>
</div>
<ol class="arabic simple" start="2">
<li><p>把均衡器放进 RADOS:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">bin</span><span class="o">/</span><span class="n">rados</span> <span class="n">put</span> <span class="o">--</span><span class="n">pool</span><span class="o">=</span><span class="n">cephfs_metadata_a</span> <span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span> <span class="o">../</span><span class="n">src</span><span class="o">/</span><span class="n">mds</span><span class="o">/</span><span class="n">balancers</span><span class="o">/</span><span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span>
</pre></div>
</div>
<ol class="arabic simple" start="3">
<li><p>激活 Mantle:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span> <span class="n">fs</span> <span class="nb">set</span> <span class="n">cephfs</span> <span class="n">max_mds</span> <span class="mi">5</span>
<span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span> <span class="n">fs</span> <span class="nb">set</span> <span class="n">cephfs_a</span> <span class="n">balancer</span> <span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span>
</pre></div>
</div>
<ol class="arabic simple" start="4">
<li><p>在另一个窗口，挂载 CephFS ：</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span><span class="o">-</span><span class="n">fuse</span> <span class="o">/</span><span class="n">cephfs</span> <span class="o">-</span><span class="n">o</span> <span class="n">allow_other</span> <span class="o">&amp;</span>
<span class="n">tail</span> <span class="o">-</span><span class="n">f</span> <span class="n">out</span><span class="o">/</span><span class="n">mds</span><span class="o">.</span><span class="n">a</span><span class="o">.</span><span class="n">log</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>注意，如果查看最后一个 MDS （可能是 a 、 b 或 c --
它是随机的。你会看到索引零值的尝试。这是因为最后一个 MDS 试图检查其邻居的负载，而邻居并不存在。</p>
</div>
<ol class="arabic simple" start="5">
<li><p>运行个简单的压力测试。我们用的是 Docker mdtest 映像，用它产生负载：</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>for i in 0 1 2; do
  docker run -d \
    --name=client$i \
    -v /cephfs:/cephfs \
    michaelsevilla/mdtest \
    -F -C -n 100000 -d &quot;/cephfs/client-test$i&quot;
done
</pre></div>
</div>
<ol class="arabic simple" start="6">
<li><p>结束后，用下列命令清理客户端：</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>for i in 0 1 2 3; do docker rm -f client$i; done
</pre></div>
</div>
</section>
<section id="id1">
<h3>输出解析<a class="headerlink" href="#id1" title="Permalink to this heading"></a></h3>
<p>查看第一个 MDS （可能是 a 、 b 或 c ）的日志，看到大家都没有负载：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:44:01.763930 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.763966 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.763982 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.764010 7fd03aaf7700  2 lua.balancer when: not migrating! my_load=0.0 hisload=0.0
2016-08-21 06:44:01.764033 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={}
</pre></div>
</div>
<p>作业开始后， MDS0 有大概 1953 个单位的负载。
激进的分配均衡器决定，将一半的负载分配给邻居 MDS ，
因此我们看到 Mantle 尝试将 1953 个负载单位发送到 MDS1。</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:45:21.869994 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=5834.188908912 all.meta_load=1953.3492228857 req_rate=12591.0 queue_len=1075.0 cpu_load_avg=3.05 &gt; load=1953.3492228857
2016-08-21 06:45:21.870017 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 &gt; load=0.0
2016-08-21 06:45:21.870027 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 &gt; load=0.0
2016-08-21 06:45:21.870034 7fd03aaf7700  2 lua.balancer when: migrating! my_load=1953.3492228857 hisload=0.0
2016-08-21 06:45:21.870050 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={0=0,1=976.675,2=0}
2016-08-21 06:45:21.870094 7fd03aaf7700  0 mds.0.bal    - exporting [0,0.52287 1.04574] 1030.88 to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690]
2016-08-21 06:45:21.870151 7fd03aaf7700  0 mds.0.migrator nicely exporting to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690]
</pre></div>
</div>
<p>最终，负载只是到处移动：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:47:10.210253 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=415.77414300449 all.meta_load=415.79000078186 req_rate=82813.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=415.79000078186
2016-08-21 06:47:10.210277 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=228.72023977691 all.meta_load=186.5606496623 req_rate=28580.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=186.5606496623
2016-08-21 06:47:10.210290 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=0.0
2016-08-21 06:47:10.210298 7fd03aaf7700  2 lua.balancer when: not migrating! my_load=415.79000078186 hisload=186.5606496623
2016-08-21 06:47:10.210311 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={}
</pre></div>
</div>
</section>
</section>
<section id="id2">
<h2>实现细节<a class="headerlink" href="#id2" title="Permalink to this heading"></a></h2>
<p>大部分实现都在 MDBalancer 里面。度量指标通过 Lua 栈传递给均衡策略，
负载列表则返回给 MDBalancer 。它与当前的均衡器实现并存，可通过 Ceph CLI 命令
（ <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">fs</span> <span class="pre">set</span> <span class="pre">cephfs</span> <span class="pre">balancer</span> <span class="pre">mybalancer.lua</span></code> ）启用。如果 Lua 策略失效
（无论出于何种原因），将回退到最初的元数据负载均衡器。这个均衡器存储在
RADOS 元数据存储池中， MDSMap 中的字符串会告诉 MDS 使用哪个均衡器。</p>
<section id="lua">
<h3>把指标暴露给 Lua<a class="headerlink" href="#lua" title="Permalink to this heading"></a></h3>
<p>度量指标作为全局变量直接暴露给 Lua 代码，而不是用明确定义的函数符号。
有一个全局 “mds” 表，其中每个索引都是一个 MDS 编号（例如 0），
每个值都是指标和值组成的字典。 Lua 代码可以用类似下面的方法获取指标：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mds</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;queue_len&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>这与 OSD 中的 cls-lua 形成鲜明对比，后者有明确定义的参数
（例如输入/输出缓冲列表）。直接暴露指标可以更方便地增加新指标，
而无需更改 Lua 这边的 API ；我们想让 API 能随着我们对指标的探索而自如地扩展和收缩。
这种方法的缺点是，做 Lua 均衡策略编程的人员必须查看 Ceph 源代码，
才能知道暴露了哪些指标。我们认为，
Mantle 开发人员无论如何都得接触 MDS 的内部结构。</p>
<p>暴露给 Lua 策略的指标与已存储在 mds_load_t 中的指标相同： auth.meta_load() 、
all.meta_load() 、 req_rate 、 queue_length 、 cpu_load_avg。</p>
</section>
<section id="id3">
<h3>编译、执行均衡器<a class="headerlink" href="#id3" title="Permalink to this heading"></a></h3>
<p>这里我们使用 <cite>lua_pcall</cite> 而不是 <cite>lua_call</cite> ，是因为我们想在 MDBalancer 中处理错误。我们不希望错误沿着调用链传播出去。 cls_lua 类希望自己处理错误，
因为它必须可控地失败。对于 Mantle 而言，我们不在乎 Lua 错误是否会导致均衡器崩溃，如果遇到了，我们就回退到原来的均衡器。</p>
<p>使用 <cite>lua_call</cite> 而不是 <cite>lua_pcall</cite> 带来的性能提升没多大影响，
因为均衡器默认每 10 秒调用一次。</p>
</section>
<section id="c">
<h3>把策略的决策返回给 C++<a class="headerlink" href="#c" title="Permalink to this heading"></a></h3>
<p>我们强制 Lua 策略引擎返回一个张表的数值，
这些值对应发送到每个 MDS 的负载量。
这些负载会直接插入 MDBalancer 的 my_targets 向量中。
我们不允许 MDS 返回 MDS 和指标表，
因为我们希望完全由 Lua 做出决策。</p>
<p>遍历 Lua 返回的表是通过堆栈完成的。
用 Lua 的行话说就是：一个假值被推到堆栈上，
下一个迭代器用 (k, v) 对替换堆栈顶部。读取每个值后，
弹出该值，但保留键，用于下一次调用 <cite>lua_next</cite> 。</p>
</section>
<section id="rados">
<h3>从 RADOS 读取<a class="headerlink" href="#rados" title="Permalink to this heading"></a></h3>
<p>当 MDS 运行图中的均衡器版本变化时，所有 MDS 都将从 RADOS 读取均衡代码。
均衡器从 RADOS 同步地读取 Lua 代码。这个操作带超时限制：
如果异步读取没有在半个均衡时间间隔内返回，操作就会被取消，
并返回 Connection Timeout （连接超时）错误。默认情况下，
均衡时间间隔为 10 秒，这样 Mantle 的超时时间是 5 秒。
这种设计会让 Mantle 在任何与 RADOS 相关的操作出错时立即返回错误信息。</p>
<p>我们用这种实现方式，是因为我们不想在全局 MDS 锁内进行阻塞式 OSD 读取。
如果有哪个 OSD 没有响应，这样做会导致 MDS 集群宕机 --
这在 ceph-qa-suite 中测试过了，把所有 OSD 设置为 down/out ，并确保 MDS 集群保持活跃。</p>
<p>一种方法是在处理 MDS 运行图时异步触发读取，并在后台装入 Lua 代码。
我们不能这样做，因为 MDS 不支持守护进程本地回退，
而且均衡器假定所有 MDS 都在同一时间做出相同的决策（例如，导入器、导出器等）。</p>
</section>
<section id="id4">
<h3>调试<a class="headerlink" href="#id4" title="Permalink to this heading"></a></h3>
<p>Lua 策略中的日志将显示在 MDS 日志中。语法与 cls 日志接口相同：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BAL_LOG</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;this is a log message&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>它是通过传递一个函数来实现的，该函数使用 <cite>lua_register()</cite> 原语将 <cite>dout</cite> 日志框架( <cite>dout_wrapper</cite> ) 封装到 Lua 中。
Lua 代码实际上是在调用 C++ 中的 <cite>dout</cite> 函数。</p>
<p>Warning 和 Info 消息通过 clog/Beacon 集中处理。
成功消息仅在第一个 MDS 进行版本变更时发送，
以避免对 <code class="docutils literal notranslate"><span class="pre">ceph</span> <span class="pre">-w</span></code> 工具产生垃圾信息。这些消息用于集成测试。</p>
</section>
<section id="id5">
<h3>测试<a class="headerlink" href="#id5" title="Permalink to this heading"></a></h3>
<p>测试使用 ceph-qa-suite (tasks.cephfs.test_mantle) 完成。
我们不测试无效的平衡器日志记录和实际的 Lua VM 加载。</p>
</section>
</section>
</section>



<div id="support-the-ceph-foundation" class="admonition note">
  <p class="first admonition-title">Brought to you by the Ceph Foundation</p>
  <p class="last">The Ceph Documentation is a community resource funded and hosted by the non-profit <a href="https://ceph.io/en/foundation/">Ceph Foundation</a>. If you would like to support this and our other efforts, please consider <a href="https://ceph.io/en/foundation/join/">joining now</a>.</p>
</div>


           </div>
           
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="../api/libcephfs-py/" class="btn btn-neutral float-left" title="LibCephFS (Python 接口)" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="../metrics/" class="btn btn-neutral float-right" title="指标" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).</p>
  </div>

   

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>